package com.android.dx.webanalystjx.api;

import android.util.Log;

import com.android.dx.webanalystjx.app.App;
import com.android.dx.webanalystjx.model.HttpResponse;
import com.android.dx.webanalystjx.model.MerchResponse;
import com.lg.meng.api.BaseApiManager;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import retrofit2.http.Field;

/**
 * Author: Ligang
 * Date: 2020/01/04
 * Description:
 */
public class ApiClient extends BaseApiManager<ApiService> {
    private static ApiClient instance;

    private ApiClient() {
    }

    public static ApiClient getInstance() {
        if (instance == null) {
            synchronized (ApiClient.class) {
                if (instance == null) {
                    instance = new ApiClient();
                }
            }
        }
        return instance;
    }

    @Override
    protected String baseUrl() {
        return App.HOST + "a/app/";
    }

    protected <T extends HttpResponse> Observable<T> request(final Observable<T> resultVoObservable) {
        return request(false, resultVoObservable);
    }

    protected <T extends HttpResponse> Observable<T> request(boolean noneSchedulers, final Observable<T> resultVoObservable) {
        if (noneSchedulers) {
            return resultVoObservable
                    .onErrorResumeNext(doOnHttpException(resultVoObservable))
                    .flatMap(new Function<HttpResponse, ObservableSource<T>>() {
                        @Override
                        public ObservableSource<T> apply(HttpResponse httpResponse) throws Exception {
                            return flatResponse(httpResponse);
                        }
                    })
                    .onErrorResumeNext(doOnServerResponseError(resultVoObservable));
        }
        return resultVoObservable
                .onErrorResumeNext(doOnHttpException(resultVoObservable))
                .flatMap(new Function<HttpResponse, ObservableSource<T>>() {
                    @Override
                    public ObservableSource<T> apply(HttpResponse httpResponse) throws Exception {
                        return flatResponse(httpResponse);
                    }
                })
                .onErrorResumeNext(doOnServerResponseError(resultVoObservable))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    private <T extends HttpResponse> Function<Throwable, ObservableSource<T>> doOnHttpException(final Observable<T> observable) {
        return new Function<Throwable, ObservableSource<T>>() {
            @Override
            public ObservableSource<T> apply(Throwable throwable) throws Exception {
                return Observable.error(throwable);
            }
        };
    }


    private <T extends HttpResponse> Function<Throwable, ObservableSource<T>> doOnServerResponseError(final Observable<T> observable) {
        return new Function<Throwable, ObservableSource<T>>() {
            @Override
            public ObservableSource<T> apply(Throwable throwable) throws Exception {
                if (throwable instanceof ServerResponseError) {
                    ServerResponseError serverResponseError = (ServerResponseError) throwable;
                }
                return Observable.error(throwable);
            }
        };
    }

    /**
     * 对网络接口返回的ResultVo进行分割操作
     */
    private <T> Observable<T> flatResponse(final HttpResponse resultVo) {
        return Observable.create(new ObservableOnSubscribe<T>() {

            @Override
            public void subscribe(ObservableEmitter<T> e) throws Exception {
                Log.d("ApiClient", resultVo.toString());

//                if (!AuthUtil.authCheck(resultVo.getAuthStatus())) {
//                    //如果失效 就自动登陆，再继续之前的接口
//                    DebugFileUtils.appendStartupProcess("cookie失效啦");
//                    PhoneTipUtils.buildAppTipItem("cookie失效了");
//                }

                if (resultVo.isSuccess()) {
                    e.onNext((T) resultVo);
                } else {
                    e.onError(new ServerResponseError(resultVo));
                }
                e.onComplete();
            }
        });
    }

    public Observable<HttpResponse<List<MerchResponse>>> getMechers() {
        return request(apiService.getMechers());
    }

    public Observable<HttpResponse> saveBuyer(String phone, String pt_key) {
        return request(apiService.saveBuyer(phone, pt_key));
    }
}
